﻿//-------------------------------------------------------------------------------
// File Name:	comm.h
// Brief: 
// Version:		1.0.0
// Create Date: 2017/05/08
// Create by: 	Marshal Lee
// Copyright: 
//				Copyright (c)  2017, Richpeace Co., LTD.
//				All rights reserved.
//
// Modify by:	Marshal Lee
// Modify Date:	2017/05/08
//-------------------------------------------------------------------------------

#ifndef __COMM_H__
#define __COMM_H__

#include "typedef.h"
#include <string.h>
#include <QDebug>
#include <stdio.h>
//------------------------------------------------------------------------

// 通讯数据包定义

//------------------------------------
/*
一、数据包格式

	1. 固定长度数据包格式

		|-------------------------------------------------------------------|-----------|
		|	数据识别序列		|					数据内容						|	校验字	|
		|-------------------------------------------------------------------|-----------|
		|	B0	B1	B2	B3	|	B4	B5	|	B6	B7	B8	B9	B10	B11	B12	B13	|	B14	B15	|
		|-------------------------------------------------------------------|-----------|
		|	固定序列如下		|			|		参数，不同命令定义不同		| B4--B13的	|
		|					|  数据包ID	|		具体定义参考命令详细说明		|			|
		|  'F','L','D','P'	| 			|									|  16位CRC	|
		|-------------------------------------------------------------------|-----------|

	2. 可变长度数据包格式

		|---------------------------------------------------------------------------|-----------|----------------
		|	数据识别序列		|					数据内容								|	校验字	|	附加数据		|
		|---------------------------------------------------------------------------|-----------|---------------|
		|	B0	B1	B2	B3	|	B4	B5	|	B6	B7	|	B8	B9	|	B10	B11	B12	B13	|	B14	B15	|	B16--Bn		|
		|---------------------------------------------------------------------------|-----------|---------------|
        |	固定序列如下		|			|	附加	|	附加	|	参数，不同命令             | B4--B13的	|	数据内容		|
        |					|  数据包ID	|	数据	|	数据	|	定义不同，定义             |			|				|
        |  'V','L','D','P'	| 			|	长度	|  校验字	|  参考命令详细说明            |  16位CRC	|				|
		|---------------------------------------------------------------------------|-----------|---------------|

		附加数据长度取值范围为 0--1024
*/

//------------------------------------

#define	DP_SYNC_LEN		4		// 数据识别序列长度
#define	DP_CONT_LEN		10		// 数据内容长度
#define	DP_CRC_LEN		2		// 校验字长度
#define	MAX_EXDP_LEN	1024	// 最大附加数据长度

#define	LEN_NORMAL_PACKET	(DP_SYNC_LEN+DP_CONT_LEN+DP_CRC_LEN)

#define	MAX_INDP_PARA	8

#ifdef _IN_COMM_CPP

const u8 FLDP_SYNC[DP_SYNC_LEN] = 
{
	'F','L','D','P',
};

const u8 VLDP_SYNC[DP_SYNC_LEN] = 
{
	'V','L','D','P',
};

#else

extern const u8 FLDP_SYNC[DP_SYNC_LEN];
extern const u8 VLDP_SYNC[DP_SYNC_LEN];

#endif

//-----------------------------------------------------------------------

typedef union 
{
	u8 datbuff[LEN_NORMAL_PACKET+MAX_EXDP_LEN];	// dat buff 方式

	struct
	{
		u8 normal[LEN_NORMAL_PACKET];
		u8 exData[MAX_EXDP_LEN];
	} __attribute__ ((packed)) buff;			// buff方式

	struct
	{
		u8 sync[DP_SYNC_LEN];
		u8 content[DP_CONT_LEN];
		u16 crc;
	} __attribute__ ((packed)) normal;			// 通用方式

	struct
	{
		u8 sync[DP_SYNC_LEN];
		u16 cmd;
		u8 para[8];
		u16 crc;
	} __attribute__ ((packed)) fldp;			// fldp方式

	struct
	{
		u8 sync[DP_SYNC_LEN];
		u16 cmd;
		u16 exlen;
		u16 excrc;
		u8 para[4];
		u16 crc;
		u8 exData[MAX_EXDP_LEN];
	} __attribute__ ((packed)) vldp;			// vldp方式

} DataPacket;

//-----------------------------------------------------------------------

typedef struct
{
    int (*sendCommData)(u8 *, int);
    int (*getCommData)(u8 *, int);
    int (*getRsvLen)(void);
    int (*getTrsFreeLen)(void);
    void (*delay)(u32);
} DataExFuns;


//-----------------------------------------------------------------------

// 读空缓冲区
void readBuffEmpty(DataExFuns * funs);


//-----------------------------------------------------------------------

// 功能: 从通讯口接收缓冲区中得到一个数据包, 
//		 只能取得普通数据包结构. 如果数据包还有附加数据, 那么需要用 GetExCommData 函数取得
// 参数: pPacket, 数据包指针
// 返回: >=0, 成功取得一个数据包，包括定长数据包和可变长度数据包，返回值为数据包长度
//		 -1, 参数错误
//		 -2, CRC错误
//		 -3, 数据不足
//		 -4, 没有找到同步序列
//		 -5，等待接收数据超时
//		 -6, 数据包参数错误
//		 -7, 附加数据CRC错误
// 		 -8, 发生未知错误

// 结果: 如果正确取得数据包，或通讯口没有命令, 循环队列尾指针回向后移动

#define	MAX_ONCE_SCAN	(LEN_NORMAL_PACKET*10)		// 一次扫描最大字节数
#define	GTEX_TIME_OUT	100							// 得到数据包超时时间，单位是ms

int getANormalPacket(DataExFuns * funs, DataPacket * pPacket);

//--------------------------------------------------------------------------------------------------

// 功能: 添加数据到发送队列中, 通过通讯口发送数据
// 参数: pPacket, 需要发送的数据，已经正确存放在了相应字段。
// 结果: 
//		 0, 可以发送, 添加到了发送数据队列中
//		 -1, 参数错误
//		 -2，发送错误
//		 1, 队列已满, 不能发送
int sendAPacket(DataExFuns * funs, DataPacket * pPacket);

//--------------------------------------------------------------------------------------------------

// 功能: 打包一个固定长度数据包
// 参数:
//		 pPacket, 需要打包的数据包，其中除了sync和crc的部分已经就绪
// 结果: 
//		 0, 打包好数据
//		 -1, 参数错误

int packetAFLDP(DataPacket * pPacket);

//--------------------------------------------------------------------------------------------------

// 功能: 打包一个可变长度数据包
// 参数: pPacket, 需要打包的数据包，需要填充其中的 SYNC EXLEN EXCRC 和 EXDAT 等部分
//		 pExdat, 附加数据，可以为空
//		 exlen，附加数据长度，可以为0
// 结果: 
//		 0, 打包好数据
//		 -1, 参数错误
//		 -2，

int packetAVLDP(DataPacket * pPacket, u8 * pExdat, u16 exlen);

//--------------------------------------------------------------------------------------------------


#endif
